package exp5;

//---------------------------------------------------------------
//  SocketServer_5.java   Author: 唐才铭   Date：2018-06-13
//
//  基于Java Socket实现服务器功能，传输方式用TCP
//  接收到后缀表达式表达式后，进行解密，解密后计算明文的MD5值，
//  和客户端传来的MD5进行比较，一致则调用MyDC.java的功能计算后缀表达式的值，
//  把结果发送给客户端.
//---------------------------------------------------------------
import javax.crypto.KeyAgreement;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.PrivateKey;
import java.security.PublicKey;

/**
 * Created by besti on 2018/6/9.
 */
public class SocketServer_5 {
    public static void main(String[] args) throws IOException {
        //1.建立一个服务器Socket(ServerSocket)绑定指定端口
        ServerSocket serverSocket=new ServerSocket(8800);
        //2.使用accept()方法阻止等待监听，获得新连接
        Socket socket=serverSocket.accept();
        //3.获得输入流
        InputStream inputStream=socket.getInputStream();
        BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream,"UTF-8"));
        //获得输出流
        OutputStream outputStream=socket.getOutputStream();
        PrintWriter printWriter=new PrintWriter(outputStream);
        //4.读取用户输入信息
        String info,info1,info2,info3,info4,info5 = null,reply = null;
        info = bufferedReader.readLine();
        System.out.println("我是服务器，用户信息为：" + info);
        String[] history = info.split("###");
        info1 = history[0];
            System.out.println("我是服务器，用户明文为：" + info1);
        info2 = history[1];
        System.out.println("我是服务器，用户明文MID5值为：" + info2);
        info3 = history[2];
        System.out.println("我是服务器，用户密文为：" + info3);
        info4 = history[3];
        System.out.println("我是服务器，用户密文MID5值为：" + info4);

        //接收到后缀表达式表达式后，进行解密并计算器MID5值
        try {
            info3 = SDec.decode(info3);
            info5 = DigestPass.MD5(info3);
            System.out.println("解密后求得的MID5：" + info5);
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 客户端和服务器用DH算法进行3DES或AES算法的密钥交换
        try{
            // 读取对方的DH公钥
            FileInputStream f1=new FileInputStream("Apub.dat");
            ObjectInputStream b1=new ObjectInputStream(f1);
            PublicKey pbk=(PublicKey)b1.readObject( );
            //读取自己的DH私钥
            FileInputStream f2=new FileInputStream("Bpri.dat");
            ObjectInputStream b2=new ObjectInputStream(f2);
            PrivateKey prk=(PrivateKey)b2.readObject( );
            // 执行密钥协定
            KeyAgreement ka=KeyAgreement.getInstance("DH");
            ka.init(prk);
            ka.doPhase(pbk,true);
            System.out.println("\n" + "公钥为：");
            //生成共享信息
            byte[ ] sb=ka.generateSecret();
            for(int i=0;i<sb.length;i++){
                System.out.print(sb[i]+",");
            }
            SecretKeySpec k=new  SecretKeySpec(sb,"DESede");
        } catch (Exception e) {
            e.printStackTrace();
        }

        //调用MyDC.java的功能计算后缀表达式的值，把结果发送给客户端
        if (info2.equals(info5)) {
             reply = MyDC.suffixToArithmetic(info1);
        }
        else {
            reply = "抱歉，二者的MID5值不一致！";
        }
        printWriter.write(reply);
        printWriter.flush();
        //5.关闭资源
        printWriter.close();
        outputStream.close();
        bufferedReader.close();
        inputStream.close();
        socket.close();
        serverSocket.close();
    }
}